﻿using System;
using RestSharp;
using System.Web;
using System.Web.WebPages;
using Newtonsoft.Json.Linq;
using Ayatta.Contract.Domain;
using Ayatta.Contract.Component;

namespace Web.Base.OAuth
{
    /// <summary>
    /// QQ
    /// </summary>
    internal sealed class QqClient : OAuthClient
    {
        public QqClient(OAuthConfig configuration): base(configuration)
        {
        }

        #region Overrides of OAuthClient

        protected override SkResult<ExternalUser> Callback(IRestResponse response)
        {
            //https://graph.qq.com/oauth2.0/token
            var content = response.Content;
            var result = new SkResult<ExternalUser>();
            if (content.Contains("callback"))
            {
                var lpos = content.IndexOf('(');
                var rpos = content.IndexOf(')');
                content = content.Substring(lpos + 1, rpos - lpos - 1);

                JToken error;
                var data = JObject.Parse(content);

                if (data.TryGetValue(ErrorKey, out error))
                {
                    result.Extra = content;
                    result.Message = error.Value<string>();
                    return result;
                }
            }
            var param = HttpUtility.ParseQueryString(content);

            var user = new ExternalUser();
            var accessToken = param[AccessTokenKey];
            var expiresIn = param[ExpiresInKey].AsInt();
            user.AccessToken = accessToken;
            user.ExpirationTime = DateTime.Now.AddSeconds(expiresIn);

            if (!string.IsNullOrEmpty(accessToken))
            {
                var request = new RestRequest(Config.UserInfoResource);
                request.AddParameter(AccessTokenKey, accessToken);
                content = Client.Execute(request).Content;

                var lpos = content.IndexOf('(');
                var rpos = content.IndexOf(')');
                content = content.Substring(lpos + 1, rpos - lpos - 1);

                try
                {
                    JToken error;
                    var data = JObject.Parse(content);
                    
                    if (data.TryGetValue(ErrorKey,out error))
                    {
                        result.Extra = content;
                        result.Message = error.Value<string>();
                        return result;
                    }

                    user.OpenId = data["openid"].Value<string>();

                    result.Data = user;
                    result.Status = true;
                }
                catch (Exception e)
                {
                    result.Extra = content;
                    result.Message = e.Message;
                }
            }
            return result;
        }
        #endregion
    }
}